
package com.google.code.sms.android.service;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Set;

import com.google.code.sms.android.domain.IndexElement;
import com.google.code.sms.android.domain.Indexes;
import com.google.code.sms.android.domain.MediaElement;
import com.google.code.sms.android.domain.MediaFolder;
import com.google.code.sms.android.domain.Playlist;
import com.google.code.sms.android.domain.SearchCritera;
import com.google.code.sms.android.domain.SearchResult;
import com.google.code.sms.android.util.Constants;
import com.google.code.sms.android.util.FileUtil;
import com.google.code.sms.android.util.ProgressListener;
import com.google.code.sms.android.util.Util;

/**
 * @author Sindre Mehus
 */
public class OfflineMusicService extends RESTMusicService 
{
    @Override
    public Indexes getIndexes(String mediaFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
        List<IndexElement> artists = new ArrayList<IndexElement>();
        File root = FileUtil.getMediaDirectory(context);
        for (File file : FileUtil.listFiles(root)) {
            if (file.isDirectory()) {
                IndexElement artist = new IndexElement();
                artist.setId(file.getPath());
                artist.setIndex(file.getName().substring(0, 1));
                artist.setName(file.getName());
                artists.add(artist);
            }
        }
        return new Indexes(artists);
    }

    @Override
    public MediaElement getMediaDirectory(String id, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
        File dir = new File(id);
        MediaElement result = new MediaElement();
        result.setName(dir.getName());

        Set<String> names = new HashSet<String>();

        for (File file : FileUtil.listMusicFiles(dir)) {
            String name = getName(file);
            if (name != null & !names.contains(name)) {
                names.add(name);
                result.addChild(createEntry(context, file, name));
            }
        }
        return result;
    }

    private String getName(File file) {
        String name = file.getName();
        if (file.isDirectory()) {
            return name;
        }

        if (name.endsWith(".partial") || name.contains(".partial.") || name.equals(Constants.ALBUM_ART_FILE)) {
            return null;
        }

        name = name.replace(".complete", "");
        return FileUtil.getBaseName(name);
    }

    private MediaElement.Entry createEntry(Context context, File file, String name) {
        MediaElement.Entry entry = new MediaElement.Entry();
        if(file.isDirectory())
        {
        	entry.setMediaType("DIRECTORY");
        }
        entry.setId(file.getPath());
        entry.setParent(file.getParent());
        entry.setSize(file.length());
        String root = FileUtil.getMediaDirectory(context).getPath();
        entry.setPath(file.getPath().replaceFirst("^" + root + "/" , ""));
        if (file.isFile()) {
            entry.setArtist(file.getParentFile().getParentFile().getName());
            entry.setAlbum(file.getParentFile().getName());
        }
        entry.setName(name);

        File albumArt = FileUtil.getAlbumArtFile(context, entry);
        if (albumArt.exists()) {
            entry.setCoverArt(albumArt.getPath());
        }
        return entry;
    }

    @Override
    public Bitmap getCoverArt(Context context, MediaElement.Entry entry, int size, boolean saveToFile, ProgressListener progressListener) throws Exception {
        InputStream in = new FileInputStream(entry.getCoverArt());
        try {
            byte[] bytes = Util.toByteArray(in);
            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            return Bitmap.createScaledBitmap(bitmap, size, size, true);
        } finally {
            Util.close(in);
        }
    }

    @Override
    public List<MediaFolder> getMediaFolders(boolean refresh, Context context, ProgressListener progressListener) throws Exception {
        throw new OfflineException("Music folders not available in offline mode");
    }

    @Override
    public SearchResult search(SearchCritera criteria, Context context, ProgressListener progressListener) throws Exception {
        throw new OfflineException("Search not available in offline mode");
    }

    @Override
    public List<Playlist> getPlaylists(boolean refresh, Context context, ProgressListener progressListener) throws Exception {
        throw new OfflineException("Playlists not available in offline mode");
    }

    @Override
    public MediaElement getPlaylist(String id, Context context, ProgressListener progressListener) throws Exception {
        throw new OfflineException("Playlists not available in offline mode");
    }

    @Override
    public void createPlaylist(String id, String name, List<MediaElement.Entry> entries, Context context, ProgressListener progressListener) throws Exception {
        throw new OfflineException("Playlists not available in offline mode");
    }

    @Override
    public MediaElement getAlbumList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception {
        throw new OfflineException("Album lists not available in offline mode");
    }

    @Override
    public String getVideoUrl(Context context, String id) {
        return null;
    }
}
